package com.uum.blog.controller;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.net.Ipv4Util;
import cn.hutool.extra.servlet.ServletUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.uum.blog.pojo.entity.Blog;
import com.uum.blog.pojo.entity.Category;
import com.uum.blog.pojo.entity.Comment;
import com.uum.blog.pojo.entity.Tag;
import com.uum.blog.pojo.form.BlogForm;
import com.uum.blog.pojo.query.BlogPageQuery;
import com.uum.blog.pojo.vo.BlogVO;
import com.uum.blog.pojo.vo.CommentVO;
import com.uum.blog.service.*;
import com.uum.blog.util.MarkdownUtils;
import com.uum.common.core.result.Result;
import com.uum.web.util.IpUtils;
import com.uum.web.util.JwtUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Api(tags = "门户接口")
@RequiredArgsConstructor
@RestController
@RequestMapping("/api/v2/door")
public class WebController {

    private final EsBlogService esBlogService;
    private final TagService tagService;
    private final CategoryService categoryService;
    private final CommentService commentService;
    private final RedisTemplate redisTemplate;
    private final BlogService blogService;

    @ApiOperation(value = "博文列表分页")
    @GetMapping("pageBlog")
    public Result blogPage(BlogPageQuery pageQuery) {
        Map page = esBlogService.webBlogPage(pageQuery);
        return Result.success(page);
    }

    @ApiOperation(value = "置顶博文")
    @GetMapping("top")
    public Result top() {
        BlogVO top = blogService.getTop();
        top.setContent(top.getContent().substring(0,200));
        return Result.success(top);
    }

    @ApiOperation(value = "根据标签或分类查询博文列表分页")
    @GetMapping("pageBlogForTagOrCategory")
    public Result pageBlogForTagOrCategory(BlogPageQuery pageQuery) {
        Map page = esBlogService.webBlogPage(pageQuery);
        Long categoryId = pageQuery.getCategoryId();
        if (categoryId != null) {
            Category category = categoryService.getOne(new LambdaQueryWrapper<Category>().eq(Category::getId, categoryId));
            page.put("detail",category);
        }

        List<Long> tagIds = pageQuery.getTagIds();
        if (CollUtil.isNotEmpty(tagIds)) {
            Tag tag = tagService.getOne(new LambdaQueryWrapper<Tag>().eq(Tag::getId, tagIds.get(0)));
            page.put("detail",tag);
        }
        return Result.success(page);
    }


    @ApiOperation(value = "获取搜索建议")
    @GetMapping("listSuggest")
    public Result listSuggest(@RequestParam String title){
        List<Map<String,String>> suggestList = esBlogService.listSuggest(title);
        return Result.success(suggestList);
    }

    @ApiOperation(value = "获取热门文章")
    @Cacheable(cacheNames = "web",key = "'hotblog'",sync = true)
    @GetMapping("listHotBlog")
    public Result listHotBlog(){
        List<Map<String, Object>> list = esBlogService.listHotBlog();
        return Result.success(list);
    }

    @ApiOperation(value = "博文详情")
    @GetMapping("detail/{id}")
    public Result blogDetail(@PathVariable Long id) {
        ServletRequestAttributes servletRequestAttributes = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
        HttpServletRequest request = servletRequestAttributes.getRequest();
        String ip = ServletUtil.getClientIP(request);

        Map<String, Object> detail = esBlogService.detail(id);
        if (detail != null) {
            String content = (String) detail.get("content");
            String markdown = MarkdownUtils.markdownToHtmlExtensions(content);
            detail.put("content",markdown);

            Boolean hasKey = redisTemplate.hasKey("BLOG_CLICK:" + ip + "#" + id);
            if (!hasKey) {
                //给博客点击数增加
                blogService.update(new LambdaUpdateWrapper<Blog>().setSql("click_num = click_num + 1").eq(Blog::getId,id));
                Integer clickNum = (Integer) detail.get("clickNum");
                clickNum++;
                //将点赞数据保存到es
                BlogForm form = new BlogForm();
                form.setId(id);
                form.setClickNum(clickNum);
                esBlogService.update(form,false);
                //将该用户点击记录存储到redis中, 24小时后过期
                redisTemplate.opsForValue().set("BLOG_CLICK:" + ip + "#" + id, clickNum, 24, TimeUnit.HOURS);
                //将原来的数据点赞加1
                detail.put("clickNum",clickNum);
            }
        }
        return Result.success(detail);
    }

    @ApiOperation(value = "标签列表")
    @Cacheable(cacheNames = "tag",key = "'list'",sync = true)
    @GetMapping("listTag")
    public Result tagList() {
        List<Tag> list = tagService.list(new LambdaQueryWrapper<Tag>().groupBy(Tag::getName).select(Tag::getId, Tag::getName));
        return Result.success(list);
    }

    @ApiOperation(value = "分类列表")
    @Cacheable(cacheNames = "category",key = "'list'",sync = true)
    @GetMapping("listCategory")
    public Result categoryList() {
        List<Category> list = categoryService.list(new LambdaQueryWrapper<Category>().groupBy(Category::getName).select(Category::getId, Category::getName));
        return Result.success(list);
    }

    @ApiOperation(value = "根据博文ID获取评论列表")
    @GetMapping("listComment/{blogId}/{currentPage}/{pageSize}")
    public Result listComment(@PathVariable Long blogId, @PathVariable Integer currentPage, @PathVariable Integer pageSize){
        List<CommentVO> commentList = commentService.listComment(blogId);
        List<CommentVO> page = CollUtil.page(currentPage - 1, pageSize,commentList);
        return Result.success().add("page",page).add("total",commentList.size());
    }



}
